package top.lv666.graduation_design_serve.util;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.vdurmont.emoji.EmojiParser;
import org.springframework.scheduling.annotation.Async;
import top.lv666.graduation_design_serve.pojo.Attention;
import top.lv666.graduation_design_serve.pojo.Blog;
import top.lv666.graduation_design_serve.pojo.BlogLike;
import top.lv666.graduation_design_serve.pojo.BlogRef;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class Tools {
    /**
     * 计算热搜热度
     *
     * @param createTime   String 创建时间
     * @param searchNumber double 搜索量
     * @param seeNumber    double 观看量
     * @param topicNumber  double 留言量
     */
    public static double getHotSearch(
            double searchNumber,
            double seeNumber,
            double topicNumber,
            String createTime
    ) {
        double hotSearch = (searchNumber + seeNumber + topicNumber) * (topicNumber / seeNumber);
        long tm = Tools.getTimer() - getMS(createTime);
        if (tm > 604800000) {
            hotSearch = -1;
        }
        return hotSearch;
    }

    /**
     * @apiNote 对博文进行点赞等候的判断
     */
    public static List<Blog> isBlogOpt(
            HttpServletRequest request,
            List<Blog> blogList,
            List<BlogLike> likeInfo,
            List<BlogRef> blogRefs,
            List<Attention> attentions
    ) {
        // 首先获取userId(用户登陆的话)
        // 确认登录

        for (Blog blog : blogList) {
            blog.setBlogContent(EmojiParser.parseToUnicode(blog.getBlogContent()));
            for (BlogLike bl : likeInfo) {
                if ((blog.getBlogID()).equals(bl.getBlogId()) && (Tools.getUserId(request)).equals(bl.getUserId())) {
                    blog.setLike(true);
                    break;
                }
            }
            for (BlogRef bl : blogRefs) {
                if ((blog.getBlogID()).equals(bl.getBlogId()) && (Tools.getUserId(request)).equals(bl.getUserId())) {
                    blog.setRef(true);
                    break;
                }
            }
            for (Attention bl : attentions) {
                if ((blog.getUserID()).equals(bl.getFollowedUserId())) {
                    blog.setAtten(true);
                    break;
                }
            }
        }
        for (Blog blog : blogList) {
            blog.setBlogContent(EmojiParser.parseToUnicode(blog.getBlogContent()));
        }
        return blogList;
    }

    /**
     * 对博文的返回数据进行处理（重载）
     */
    public static List<Blog> isBlogOpt(
            String id,
            List<Blog> blogList,
            List<BlogLike> likeInfo,
            List<BlogRef> blogRefs,
            List<Attention> attentions
    ) {

        for (Blog blog : blogList) {
            blog.setBlogContent(EmojiParser.parseToUnicode(blog.getBlogContent()));
            for (BlogLike bl : likeInfo) {
                if ((blog.getBlogID()).equals(bl.getBlogId()) && (id).equals(bl.getUserId())) {
                    blog.setLike(true);
                    break;
                }
            }
            for (BlogRef bl : blogRefs) {
                if ((blog.getBlogID()).equals(bl.getBlogId()) && (id).equals(bl.getUserId())) {
                    blog.setRef(true);
                    break;
                }
            }
            for (Attention bl : attentions) {
                if ((blog.getUserID()).equals(bl.getFollowedUserId())) {
                    blog.setAtten(true);
                    break;
                }
            }
        }
        return blogList;
    }

    /**
     * @apiNote 对博文进行点赞等候的判断 重载
     */
    public static List<Blog> isBlogOpt(
            HttpServletRequest request,
            List<Blog> blogList
    ) {
        for (Blog blog : blogList) {
            blog.setBlogContent(EmojiParser.parseToUnicode(blog.getBlogContent()));
        }
        return blogList;
    }

    /**
     * @apiNote 判断一个map是否为空，以及key中是否有null
     */
    public static void isMapNull(Map<String, Object> map) {
        //判断hashmap是否有值
        if (map == null || map.isEmpty()) {
            throw new Error("传值为空！");
        }

        //判断传来的所有数值是否为空
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            //entry.getKey();
            if (entry.getValue().equals("") || entry.getValue() == null) {
                throw new Error("【" + entry.getKey() + "】数据格式错误！");
            }
        }
    }

    /**
     * @apiNote 生成一个UUID
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * @apiNote 获取系统当前系统时间
     */
    public static long getTimer() {
        return System.currentTimeMillis();
    }

    /**
     * @param sendTitle 要发送邮件的标题
     * @param sendText  要发送邮件的内容
     * @param sendUser  要发给用户的Email
     * @apiNote 发送QQ邮件
     */
    public static void SendQQMail(String sendTitle, String sendText, String sendUser) throws Exception {
        Properties properties = new Properties();
        properties.put("mail.transport.protocol", "smtp");// 连接协议
        properties.put("mail.smtp.host", "smtp.qq.com");// 主机名
        properties.put("mail.smtp.port", 587);// 端口号
        properties.put("mail.smtp.auth", "true");
        //properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用
        // 得到回话对象
        Session session = Session.getInstance(properties);
        // 获取邮件对象
        Message message = new MimeMessage(session);
        // 发送文件
        // message.setFileName("Homework");
        // 设置发件人邮箱地址
        message.setFrom(new InternetAddress("lv0310@foxmail.com"));
        // 设置收件人邮箱地址
        // message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("xxx@qq.com"), new InternetAddress("xxx@qq.com"), new InternetAddress("xxx@qq.com")});
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(sendUser));//一个收件人
        // 设置邮件标题
        message.setSubject(sendTitle);
        // 设置邮件内容
        message.setContent(sendText, "text/html;charset=UTF-8");
        // 得到邮差对象
        Transport transport = session.getTransport();
        // 连接自己的邮箱账户
        transport.connect("lv0310@foxmail.com", "xcgmmjlbprnzdfhj");// 密码为QQ邮箱开通的stmp服务后得到的客户端授权码
        // 发送邮件
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();
    }

    /**
     * @apiNote 获取IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    try {
                        ipAddress = InetAddress.getLocalHost().getHostAddress();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                }
            }
            // 通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null) {
                if (ipAddress.contains(",")) {
                    return ipAddress.split(",")[0];
                } else {
                    return ipAddress;
                }
            } else {
                return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * @apiNote 获取当前时间 yyyy-MM-dd HH:mm:ss:SSS
     */
    public static String getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }

    /**
     * @apiNote 获取6位随机码
     */
    public static long getRandomCode() {
        Random rand = new Random();
        //随机码
        return rand.nextInt(899999) + 100000;
    }

    /**
     * @apiNote 计算热度
     */
    public static double getHotNumber(double zan, double comm, double tran, long createTime) {
        // Score=P/T^G
        DecimalFormat df = new DecimalFormat("0.000");
        if (Tools.getMS(Tools.getTime()) - createTime > 432000000) {
            return 0.0;
        }
        // 被除数
        double BC = zan + comm * 5 + tran * 3;
        // 除数
        double C = Math.pow((Tools.getMS(Tools.getTime()) - createTime) + 1, 1.5);
        return BC / C;
    }

    /**
     * @apiNote 获取时间戳
     */
    public static long getMS(String time) {
        Timestamp timestamp = Timestamp.valueOf(time);
        return timestamp.getTime();
    }

    /**
     * @apiNote 判断是否登录
     */
    public static Boolean isLogin(HttpServletRequest request) {
        try {
            String token = request.getHeader("Authorization");
            if (token.equals("")) {
                throw new Error("token验证失败！");
            }
            JWTUtils.verify(token);
            return true;
        } catch (Error | Exception e) {
            throw e;
        }
    }

    /**
     * @apiNote 获取用户ID
     */
    public static String getUserId(HttpServletRequest request) {
        DecodedJWT jwt = JWTUtils.getTokenInfo(request.getHeader("Authorization"));
        return jwt.getClaims().get("uId").asString();
    }
    /**
     * @apiNote Emoji->String
     * */
    // public static
}
